using UnityEngine;
using JufGame.MathHelper;

namespace JufGame.CptMod
{
	/// <summary>
	/// 注意程度：玩家对该角色的注意力的估计值
	/// </summary>
	public class Attention
	{
		public float RealAttention { get; private set; } = 0;//实际注意程度，与总注意程度负载的比值
		public float AttempAttetion { get; private set; } = 0;//尝试注意程度，初始值
		private const float MIN_ATTEMP_ATTETION = 0;//最小尝试注意力，兜底用的
		private readonly EMA ob_EMA;//观察度预测EMA
		private readonly EMA fcs_EMA;//聚焦度预测EMA
		private readonly Transform character;
		public Attention(Transform character, float fcs_k = 0.01f, float ob_k = 2f)
		{
			this.character = character;
			fcs_EMA = new EMA(fcs_k);
			ob_EMA = new EMA(ob_k);
		}
		/// <summary>
		/// 获取实际注意程度
		/// </summary>
		/// <param name="totalAtnLoad">总注意程度负载, 由LOD_Trader统一计算</param>
		public void GetRealAttention(float totalAtnLoad)
		{
			RealAttention = AttempAttetion / totalAtnLoad * 10;
		}
		/// <summary>
		/// 获取加入混合因素后的"尝试注意程度"，将其他因素用于基本尝试注意程度做加权
		/// </summary>
		public void UpdateAttempAttention(Camera camera, float obserValue, float deltaTime)
		{
			AttempAttetion = Mathf.Max(MIN_ATTEMP_ATTETION, 0.7f * BaseAttempAttention(obserValue, deltaTime) +
					0.3f * Focusing(camera, obserValue, deltaTime));//乘100确保其数量级与其它因子相当
		}
		/// <summary>
		/// 用基于可观察度的EMA作为"基本尝试注意程度”
		/// </summary>
		/// <param name="obserValue">可观察度</param>
		/// <param name="deltaTime">时间间隔</param>
		/// <returns>尝试注意程度</returns>
		private float BaseAttempAttention(float obserValue, float deltaTime)
		{
			return ob_EMA.CalculateEMA(obserValue, deltaTime);
		}
		/// <summary>
		/// 基于相机向量与相机到玩家的向量的点积的EMA
		/// </summary>
		/// <param name="obserValue">可观察度</param>
		/// <param name="deltaTime">时间间隔</param>
		/// <returns>聚焦度</returns>
		private float Focusing(Camera camera, float obserValue, float deltaTime)
		{
			var dot = Mathf.Max(0, Vector3.Dot(camera.transform.forward - camera.transform.position, 
			character.transform.position - camera.transform.position));
			return fcs_EMA.CalculateEMA(dot, deltaTime) * obserValue;
		}
	}
}
